import datetime
from decimal import Decimal
from typing import List

from module_admin.casdoor.user import NewUser
from module_admin.dao.cms_car_dao import CmsCarDao
from module_admin.dao.cms_driver_dao import CmsDriverDao
from module_admin.dao.cms_order_bill_dao import CmsOrderBillDao
from module_admin.dao.cms_order_dao import CmsOrderDao
from module_admin.dao.cms_order_dispatch_dao import CmsOrderDispatchDao
from module_admin.dao.cms_order_execute_dao import CmsOrderExecuteDao
from module_admin.dao.dept_dao import *
from module_admin.entity.do.cms_car import CmsCar
from module_admin.entity.do.cms_driver import CmsDriver
from module_admin.entity.do.cms_order import CmsOrder
from module_admin.entity.do.cms_order_bill import CmsOrderBill
from module_admin.entity.do.cms_order_dispatch import CmsOrderDispatch
from module_admin.entity.do.cms_order_execute import CmsOrderExecute
from module_admin.entity.vo.cms_order_bill_vo import OrderBillModel, OrderBillModelForQuery, OrderBillModelForOperate, \
    OrderBillModelForUpdate, OrderBillModelForOperateBatch, OrderBillPageObject
from module_admin.entity.vo.cms_order_vo import OrderModel, CrudOrderResponse, OrderModelForQuery
from module_admin.entity.vo.data_vo import BillFileData
from module_admin.entity.vo.expense_vo import ExpensesModelForJisuan
from module_admin.enum.state_enum import OrderStateEnum
from module_admin.service.expenses_service import ExpensesService
from utils.stringUtils import stringUtils
from utils.time_format_util import export_format_datetime, export_format_datetime2
from utils.uuid import UUID
from config.config import Config


class CmsOrderBillService:
    """
    部门管理模块服务层
    """

    @classmethod
    def create_order_bill(cls, result_db: Session, page_object: OrderBillModel):
        page_object.id = int(UUID().uuid())
        return CmsOrderBillDao.create_order_bill(result_db, page_object)

    @classmethod
    def update_order(cls, db, order_update: OrderBillModel):
        order_update_dict = order_update.dict(exclude_unset=True)
        return CmsOrderBillDao.update_order_bill_by_id(db, order_update_dict)

    @classmethod
    def get_order(cls, query_db: Session, id: int):
        order_by_id: CmsOrderBill = CmsOrderBillDao.get_one_by_id(query_db, id)
        return OrderModel(**order_by_id.__dict__)

    @classmethod
    def settlement(cls, query_db: Session, order_bill_operate: OrderBillModelForOperate):
        order_by_id: CmsOrderBill = CmsOrderBillDao.get_one_by_id(query_db, order_bill_operate.id)
        if order_by_id is None:
            return
        if order_bill_operate.operate == "作废":
            order_by_id.state = "作废"
        elif order_bill_operate.operate == "结算":
            order_by_id.state = "已结算"
            order_by_id.expenses = order_bill_operate.expenses

        cls.update_order(query_db, OrderBillModel(**order_by_id.__dict__))

    @classmethod
    def settlement_list(cls, query_db, order_bill_opeate_list: List[int]):
        for bill_id in order_bill_opeate_list:
            order_by_id: CmsOrderBill = CmsOrderBillDao.get_one_by_id(query_db, bill_id)
            if order_by_id is None:
                break
            order_by_id.state = "已结算"
            cls.update_order(query_db, OrderBillModel(**order_by_id.__dict__))

    @classmethod
    def list(cls, db: Session, query_object: OrderBillModelForQuery):

        order_list_result = CmsOrderBillDao.list(db, query_object)
        return order_list_result

    @classmethod
    def page(cls, db: Session, query_object: OrderBillPageObject):

        order_list_result = CmsOrderBillDao.page(db, query_object)
        return order_list_result

    @classmethod
    def count(cls, db: Session, query_object: OrderBillPageObject):

        order_list_result = CmsOrderBillDao.count(db, query_object)
        return order_list_result

    @classmethod
    def update_mileage(cls, db: Session, order_update: OrderBillModelForUpdate):
        try:
            order: CmsOrder = CmsOrderDao.get_order_by_id(db, order_update.id)
            if order is None:
                raise ValueError("该用车申请不存在")
            if order.state != OrderStateEnum.ywj.value:
                raise ValueError("该用车申请状态为" + OrderStateEnum.get_state_name(order.state) + "无法修改里程")
            order_bill: CmsOrderBill = CmsOrderBillDao.get_one_by_order_id(db, order.order_id)
            order_execute: CmsOrderExecute = CmsOrderExecuteDao.get_one_by_order_id(db, order.order_id)
            if order_bill is None or order_execute is None:
                raise ValueError("该用车申请状态为" + OrderStateEnum.get_state_name(order.state) + "无法修改里程")
            CmsOrderBillDao.update_order_bill_by_order_id(db, order_update, order.order_id)
            CmsOrderExecuteDao.update_execute_bill_by_order_id(db, order_update, order.order_id)
        except Exception as e:
            db.rollback()
            raise ValueError("修改里程失败" + str(e))

    @classmethod
    def get_export_data(cls, query_db: Session, order_id_str: str):
        data = BillFileData()
        order: CmsOrder = CmsOrderDao.get_order_by_str_id(query_db, order_id_str)
        if order is None:
            raise ValueError("该用车申请不存在,不允许导出")
        order_dispatch: CmsOrderDispatch = CmsOrderDispatchDao.get_one_by_order_id(query_db, order_id_str)
        if order_dispatch is None:
            raise ValueError("该用车申请未调度,不允许导出")
        order_execute: CmsOrderExecute = CmsOrderExecuteDao.get_one_by_order_id(query_db, order_id_str)
        if order_execute is None:
            raise ValueError("该用车申请司机还没开始,不允许导出")
        car: CmsCar = CmsCarDao.get_car_by_car_id(query_db, order_execute.car_id)
        if car is None:
            raise ValueError("该用车申请未分配车辆,不允许导出")
        driver: CmsDriver = CmsDriverDao.get_one_by_driver_id(query_db, order_execute.driver_id)
        if driver is None:
            raise ValueError("该用车申请未分配司机,不允许导出")
        order_bill: CmsOrderBill = CmsOrderBillDao.get_one_by_order_id(query_db, order_id_str)
        if order_bill is None:
            raise ValueError("该用车申请还没完结,不允许导出")
        # 用车部门、任务单号
        data.department_name = order.department_id
        data.order_id = order.order_id
        # 实际出发地点--实际回车地点     实际出车时间--实际回车时间
        export_str = stringUtils.get_export_str(stringUtils.get_list(order.destination))
        data.start_and_destination = order.start + "--" + export_str
        reality_begin_time = export_format_datetime(order_execute.reality_begin_time)
        reality_end_time = export_format_datetime(order_execute.reality_end_time)
        data.start_and_end_time = reality_begin_time + "--" + reality_end_time
        # 车辆类型 车型 、车牌号
        data.car_brand_and_car_type = car.car_brand + "--" + car.car_type
        data.car_number = car.car_number
        # 驾驶员、用车人
        data.driver_name = driver.driver_name
        data.use_user = order.use_user_id
        # 里程、调度员
        if order_bill.bill_type == "beidou":
            data.mileage = str(order_bill.system_mileage) + "公里"
        else:
            data.mileage = str(order_bill.sheet_mileage) + "公里"
        data.dispatch_name = order_dispatch.create_by
        # 计算费用
        get_expenses: List[ExpensesModelForJisuan] = ExpensesService.get_expenses(query_db, order_id_str)
        if get_expenses:
            qibu = Decimal("0")
            guding= Decimal("0")
            licheng= Decimal("0")
            tingyan= Decimal("0")
            for e in get_expenses:
                qibu = qibu + (e.starting_price_sum if e.starting_price_sum else Decimal("0"))
                guding = guding + (e.day_price_sum if e.day_price_sum else Decimal("0"))
                licheng = licheng + (e.miles_price_sum if e.miles_price_sum else Decimal("0"))
                tingyan = tingyan + (e.suspended_price_sum if e.suspended_price_sum else Decimal("0"))
            data.expenses = stringUtils.expense_export_str(qibu, guding, licheng, tingyan)
        # 签字图片
        data.sign = order_execute.sign
        # 导出日期
        data.export_time = export_format_datetime2(datetime.datetime.now())
        return data
